#pragma once

#include <sys/epoll.h>
#include <stdlib.h>
#include "Err.hpp"
#include <unistd.h>
#include "Log.hpp"

class Epoll
{
    static const int default_createsize = 10;

public:
    // 构造
    Epoll(int maxevents)
        : _epfd(-1), _events(nullptr), _maxevents(maxevents)
    {
    }

    // 析构
    ~Epoll()
    {
        if (_epfd >= 0)
            close(_epfd);

        if (_events)
        {
            delete[] _events;
            _events = nullptr;
        }
    }

    // 创建epoll模型
    void Create()
    {
        _epfd = epoll_create(default_createsize);
        if (_epfd < 0)
            exit(EPOLL_CREATE_FAILED);

        _events = new struct epoll_event[_maxevents]; // 给就绪数组开辟空间
    }

    // 添加/修改/删除文件描述符
    int Control(int op, int fd, struct epoll_event *event)
    {
        return epoll_ctl(_epfd, op, fd, event);
    }

    // 等待文件描述符就绪
    int wait(int timeout)
    {
        return epoll_wait(_epfd, _events, _maxevents, timeout);
    }

    // 修改就绪数组的大小
    void resize(int newsize)
    {
        delete[] _events;
        _events = new struct epoll_event[newsize];
        _maxevents = newsize;
    }

    // 获取就绪数组的大小
    size_t size()
    {
        return _maxevents;
    }

    // 获取epoll文件描述符
    int getfd()
    {
        return _epfd;
    }

    // 获取就绪列表
    const struct epoll_event *getlist()
    {
        return _events;
    }

private:
    int _epfd;                   // epoll文件描述符
    struct epoll_event *_events; // 输出型就绪文件描述符数组
    int _maxevents;              // events数组的大小
};